/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DBLager;
import java.sql.*;
import ModelLager.SupplierP;
import java.util.ArrayList;
/**
 *
 * @author Jonas Kristensen
 */
public class DbSupplierP implements IFDBSup
{
    private Connection con;
    private PreparedStatement pStmtSelect;
    
    public DbSupplierP()
    {
        con = DbConnection2.getInstance().getDBcon();
    }
    
    /*
     * Bruges til at lave et prepared statmement for at finde en specifik supplier med et bestemt id.
     */
    public PreparedStatement getPreparedStmt(String wClause)
    {
        try
        {
            String query = "SELECT name,address,country,phoneNo, email, supplierId, SupplierP.zipCode, city "
                         + "FROM SupplierP, ZipcodeCityP WHERE SupplierP.zipCode = ZipCodeCityP.zipCode ";
            if(wClause.length()>0)
            {
                query = query + "AND " + wClause;
            }
            System.out.println("Preparestatement " + query);
            pStmtSelect = con.prepareStatement(query);
            pStmtSelect.setQueryTimeout(5);
        }
        catch(Exception e)
        {
            e.getMessage();
        }
        return pStmtSelect;
    }
    
    /**
     * Her bygges objektet i java fra sql db.
     * @param results De resultater som er blevet fundet i databasen.
     * @return supplierobjekt som er blevet bygget ud fra den række der er i results.
     */
    public SupplierP buildSupplierP(ResultSet results)
    {
        SupplierP sObj = new SupplierP();
        
        try
        {
            sObj.setName(results.getString("name"));
            sObj.setAddress(results.getString("address"));
            sObj.setCountry(results.getString("country"));
            sObj.setPhoneNo(results.getString("phoneNo"));
            sObj.setEmail(results.getString("email"));
            sObj.setSupplierID(results.getInt("supplierID"));
            sObj.setZipCode(results.getString("zipCode"));
            sObj.setCity(results.getString("city"));
        }
        catch(Exception e)
        {
            System.out.println("Error in building supplierP object");
        }
        return sObj;
    }
    
    /**
     * Bruges til at finde suppler med det id der er som parameter.
     * @param supplierID id på den supplier man ønsker at finde.
     * @return null hvis den ikke finde nogen med det supplierID ellers returnere den supplierP objektet som er fundet.
     */
    public SupplierP findByIDWithPreQuery(int supplierID)
    {
        System.out.println("Find with preCompiled");
        if(pStmtSelect == null)
        {
            String wClause = "supplierID = ?";
            pStmtSelect = getPreparedStmt(wClause); // Bliver man nødt til at gøre hver gang pga. linje 91, pStmtSelect.setInt(1, supplierID);? da den ændre i pStmtSelect? 
        }    
        SupplierP sObj = null;
        ResultSet results;
        try
        {
            pStmtSelect.clearParameters(); // FORSØG
            pStmtSelect.setInt(1, supplierID);
            results = pStmtSelect.executeQuery();
            if(results.next())
            {
                sObj = buildSupplierP(results);
            }
            
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
        return sObj;
    }
    
    /**
     * Bruges til at finde alle eller nogle af supplierene
     * @param name noget af navnet på den supplier man ønsker at finde.
     * @param allNames true = alle suppliers. false = dem med noget af det søgte navn i deres navn.
     * @return ArrayList med suppler objekter.
     */
    public ArrayList<SupplierP> findByNamePreQuery(String name, boolean allNames)
    {
        System.out.println("Find with preCompiled");
        ArrayList<SupplierP> list = new ArrayList<SupplierP>();
        String parameter ="";
        String wClause = "";
//        if(pStmtSelect == null)
//        {
        if(!allNames)
            {
                wClause = "name like ?";
            }
            else
            {
                wClause ="";
            }
            pStmtSelect = getPreparedStmt(wClause); // se linje 85.
//        }
        SupplierP sObj = null;
        ResultSet results;
        try
        {
            if(!allNames)
            {
                parameter = "%"+name+"%"; // betyder at det der står foran navn og efter navn kommer med i resultaterne. f.eks. Søg på john og du får johnson + andre med john i deres navn.
                pStmtSelect.clearParameters(); //FORSØG
                pStmtSelect.setString(1, parameter);
            }
            
            results = pStmtSelect.executeQuery();
            while(results.next())
            {
                sObj = buildSupplierP(results);
                list.add(sObj);
            }
            pStmtSelect.close();
        }
        catch(Exception e)
        {
            System.out.println("ERROR: " + e.getMessage());
        }
        return list;    
    }

    /**
     * Finder supplieren med supplierID
     * @param supplierID ID på den supplier man vil finde
     * @return null eller supplier objekt
     */
    public SupplierP findSupplier(int supplierID)
    {
        SupplierP supObj = findByIDWithPreQuery(supplierID);
        
        return supObj;
    }
    
    /**
     * Find supplers med "name" i deres navn.
     * @param name navn man ønsker at finde resultaterne af.
     * @return ArrayListe med supplerobjekter.
     */
    public ArrayList<SupplierP> getSuppliersByName(String name)
    {
        ArrayList<SupplierP> list = findByNamePreQuery(name, false);
        return list;
    }
    
    /**
     * Returnerer alle suppleres der er i databasen.
     * @return Arrayliste med supplerobjekter.
     */
    public ArrayList<SupplierP> getAllSuppliers()
    {
        ArrayList<SupplierP> list = findByNamePreQuery("", true);
        return list;
    }
    
    /**
     * Indsætte ny suppler i databasen
     * @param sObj nyt supplerobjekt som ønskes indsat i databasen
     * @return rc returncode. -1 = fejl. 1 = ok.
     */
    public int insertSupplier(SupplierP sObj) throws SQLException, Exception
    {
        int rc = -1;
        PreparedStatement pstmt = null;
        String insert = "INSERT INTO SupplierP (name, address, country, phoneNo, email, supplierID, zipCode)" +
                        "VALUES (?,?,?,?,?,?,?)";
        System.out.println(insert);
        try
        {
            pstmt = con.prepareStatement(insert);
            pstmt.setQueryTimeout(5);
            pstmt.setString(1, sObj.getName());
            pstmt.setString(2, sObj.getAddress());
            pstmt.setString(3, sObj.getCountry());
            pstmt.setString(4, sObj.getPhoneNo());
            pstmt.setString(5, sObj.getEmail());
            pstmt.setInt(6, sObj.getSupplierID());
            pstmt.setString(7, sObj.getZipCode());
            rc = pstmt.executeUpdate();
            
            pstmt.close();
        }
        catch(SQLException sqlE)
        {
            System.out.println("SQL Error");
            System.out.println(sqlE.getMessage());
            throw new SQLException();
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
            throw new Exception();
        }
        return rc;
    }
    
    /**
     * Slet en supplier fra databasen med supplierID
     * @param supplierID ID på den supplier du vil slette
     * @return returncode. -1 = fejl. 1 = ok.
     */
    public int deleteSupplier(int supplierID)
    {
        int rc = -1;
        PreparedStatement pstmt = null;
        String delete = "DELETE FROM SupplierP WHERE supplierID = ?";
        System.out.println(delete);
        try
        {
            pstmt = con.prepareStatement(delete);
            pstmt.setQueryTimeout(5);
            pstmt.setInt(1, supplierID);
            rc = pstmt.executeUpdate();
            
            pstmt.close();
        }
        catch(SQLException sqlE)
        {
            System.out.println("SQL Error");
            System.out.println(sqlE.getMessage()); 
        }
        catch(Exception e)
        {
            e.getMessage();
        }
        return rc;
    }
    
    /**
     * Opdater en eksisterende supplier i databasen.
     * @param supplier supplier objekt som ønskes updateret
     * @return returncode. -1 = fejl. 1 = ok.
     */
    public int updateSupplier(SupplierP supplier) throws SQLException, Exception
    {
        // metoden returnerer rc = -1(rc er kort for return code), hvis ikke 'try løkken' 
        // går igennem og vil derfor returnere en fejl.
        int rc = -1;
        //opretter et tomt statement objekt
        //opretter en string der indeholder querien der skal eksekveres
        String query = null;
        
        //fordi con.prepareStatement metoden "kaster" en fejl fejl(SQLException)
        //skal koden indrammes i try/catch
        try
        {
        
            query = "UPDATE SupplierP " 
                  + "SET name = ?, address = ?, country = ?, phoneNo = ?, email = ?, supplierID = ?, zipCode = ? "
                  + "WHERE supplierID = " + supplier.getSupplierID();

            PreparedStatement preStmnt = con.prepareStatement(query);
            preStmnt.setQueryTimeout(5);
            System.out.println(query);

            preStmnt.setString(1, supplier.getName());
            preStmnt.setString(2, supplier.getAddress());
            preStmnt.setString(3, supplier.getCountry());
            preStmnt.setString(4, supplier.getPhoneNo());
            preStmnt.setString(5, supplier.getEmail());
            preStmnt.setInt(6, supplier.getSupplierID());
            preStmnt.setString(7, supplier.getZipCode());
 
            rc = preStmnt.executeUpdate();
            
            preStmnt.close();
                
        }
        catch(SQLException SQLe)
        {
            //returnerer SQL Exception
            System.out.println("SQL Error: " + SQLe.getMessage());
            throw new SQLException();
        }
        catch(Exception e)
        {
            //returnerer java exception
            System.out.println("ExceptionE: " + e.getMessage());
            throw new Exception();
        }        
        return rc;
    }
}
